package palindrome

import (
	"fmt"
	"strconv"
)

const testVersion = 1

type Product struct {
	palindrome     int
	Factorizations [][2]int
}

type ProductError struct {
	message string
}

func (e *ProductError) Error() string { return fmt.Sprintf(e.message) }

func Products(fmin, fmax int) (pMin, pMax Product, err error) {
	if fmax < fmin {
		err = &ProductError{"fmin > fmax"}
		return
	}

	productMap := make(map[int][][2]int)
	for i := fmin; i <= fmax; i++ {
		for j := i; j <= fmax; j++ {
			if r, ok := isPalindrome(i, j); ok {
				if _, has := productMap[r]; has {
					productMap[r] = append(productMap[r], [2]int{i, j})
				} else {
					productMap[r] = [][2]int{{i, j}}
				}
			}
		}
	}

	for k, v := range productMap {
		if pMin.palindrome == 0 || k < pMin.palindrome {
			pMin = Product{k, v}
		}

		if pMax.palindrome == 0 || k > pMax.palindrome {
			pMax = Product{k, v}
		}
	}

	if pMin.palindrome == 0 || pMax.palindrome == 0 {
		err = &ProductError{"no palindromes"}
		return
	}

	return
}

func isPalindrome(a, b int) (r int, ok bool) {
	r = a * b
	rS := strconv.Itoa(r)

	l := len(rS)
	for i := 0; i < l/2; i++ {
		if rS[i] != rS[l-i-1] {
			return
		}
	}
	ok = true
	return
}
